"""
过滤操作符实现
"""

from typing import Optional, List, Dict, Any, Iterator, Callable
import re
import operator
import time

from ..executor_base import IteratorExecutor
from ..types import Record, RecordBatch, ExecutionContext, DataValue
# 实现了执行器基础类
class FilterOperator(IteratorExecutor):
    """过滤操作符"""
    
    def __init__(self, executor_id: str, context: ExecutionContext,
                 child: IteratorExecutor, predicate: str):
        super().__init__(executor_id, context)
        self.child = child # 子执行器
        self.predicate_str = predicate # 谓词表达式
        self.predicate_func: Optional[Callable[[Record], bool]] = None # 谓词函数
        
        # 添加子执行器
        self.add_child(child)
        
        # 编译谓词
        self._compile_predicate(predicate)
    
    def _compile_predicate(self, predicate: str):
        """编译谓词表达式"""
        try:
            # 简化的谓词编译器
            self.predicate_func = self._create_predicate_function(predicate)
        except Exception as e:
            raise ValueError(f"Invalid predicate: {predicate}, error: {e}")
    
    def _create_predicate_function(self, predicate: str) -> Callable[[Record], bool]:
        """创建谓词函数"""
        # 简化的谓词解析，支持基本的比较操作
        predicate = predicate.strip()
        
        # 首先检查是否是复合条件
        predicate_lower = predicate.lower()
        if 'and' in predicate_lower or 'or' in predicate_lower:
            return self._create_special_predicate(predicate)
        
        # 支持的操作符
        operators_map = {
            '>=': operator.ge,
            '<=': operator.le,
            '!=': operator.ne,
            '=': operator.eq,
            '>': operator.gt,
            '<': operator.lt,
        }
        
        # 查找操作符
        op_found = None
        op_func = None
        for op_str, op_f in operators_map.items():
            if op_str in predicate:
                op_found = op_str
                op_func = op_f
                break
        
        if op_found is None:
            # 尝试处理特殊谓词
            return self._create_special_predicate(predicate)
        
        # 分割左右操作数
        left_expr, right_expr = predicate.split(op_found, 1)
        left_expr = left_expr.strip()
        right_expr = right_expr.strip()
        
        def predicate_func(record: Record) -> bool:
            try:
                # 获取左操作数值
                left_value = self._evaluate_expression(left_expr, record)
                
                # 获取右操作数值
                right_value = self._evaluate_expression(right_expr, record)
                
                # 首先尝试类型转换，确保类型兼容
                converted_left = left_value
                converted_right = right_value
                
                # 如果类型不同，尝试转换
                if type(left_value) != type(right_value):
                    # 如果一个是数字，一个是字符串，尝试统一类型
                    if isinstance(left_value, (int, float)) and isinstance(right_value, str):
                        try:
                            if '.' in right_value:
                                converted_right = float(right_value)
                            else:
                                converted_right = int(right_value)
                        except ValueError:
                            # 转换失败，将数字转为字符串
                            converted_left = str(left_value)
                    
                    elif isinstance(left_value, str) and isinstance(right_value, (int, float)):
                        try:
                            if '.' in left_value:
                                converted_left = float(left_value)
                            else:
                                converted_left = int(left_value)
                        except ValueError:
                            # 转换失败，将数字转为字符串
                            converted_right = str(right_value)
                
                # 执行比较
                return op_func(converted_left, converted_right)
            except:
                return False
        
        return predicate_func
    
    def _create_special_predicate(self, predicate: str) -> Callable[[Record], bool]:
        """创建特殊谓词函数"""
        predicate_lower = predicate.lower()
        
        # 处理复合条件（包含AND/OR）
        if 'and' in predicate_lower or 'or' in predicate_lower:
            return self._parse_complex_predicate(predicate)
        
        # IS NULL / IS NOT NULL
        elif 'is null' in predicate_lower:
            column = predicate_lower.replace('is null', '').strip()
            return lambda record: record.get(column) is None
        
        elif 'is not null' in predicate_lower:
            column = predicate_lower.replace('is not null', '').strip()
            return lambda record: record.get(column) is not None
        
        # LIKE
        elif 'like' in predicate_lower:
            parts = predicate_lower.split('like')
            if len(parts) == 2:
                column = parts[0].strip()
                pattern = parts[1].strip().strip("'\"")
                # 转换SQL LIKE模式为正则表达式
                regex_pattern = pattern.replace('%', '.*').replace('_', '.')
                compiled_regex = re.compile(regex_pattern)
                
                return lambda record: (
                    record.get(column) is not None and
                    compiled_regex.match(str(record.get(column))) is not None
                )
        
        # IN
        elif 'in' in predicate_lower:
            parts = predicate.split(' in ', 1)
            if len(parts) == 2:
                column = parts[0].strip()
                values_str = parts[1].strip().strip('()')
                values = [v.strip().strip("'\"") for v in values_str.split(',')]
                
                return lambda record: str(record.get(column)) in values
        
        # BETWEEN
        elif 'between' in predicate_lower:
            parts = predicate_lower.split('between')
            if len(parts) == 2:
                column = parts[0].strip()
                range_part = parts[1].strip()
                if 'and' in range_part:
                    range_values = range_part.split('and')
                    if len(range_values) == 2:
                        min_val = self._parse_value(range_values[0].strip())
                        max_val = self._parse_value(range_values[1].strip())
                        
                        return lambda record: (
                            record.get(column) is not None and
                            min_val <= record.get(column) <= max_val
                        )
        
        # 默认返回总是为True的谓词
        return lambda record: True
    
    def _parse_complex_predicate(self, predicate: str) -> Callable[[Record], bool]:
        """解析复合谓词表达式（包含AND/OR和括号）"""
        
        # 简化的复合谓词解析器
        predicate = predicate.strip()
        
        # 移除最外层多余的括号（但要确保括号是匹配的）
        while predicate.startswith('(') and predicate.endswith(')'):
            # 验证这是否是最外层的括号对
            paren_count = 0
            is_outermost = True
            for i, char in enumerate(predicate[1:-1]):  # 跳过第一个和最后一个字符
                if char == '(':
                    paren_count += 1
                elif char == ')':
                    paren_count -= 1
                    if paren_count < 0:  # 右括号太多，说明不是最外层括号
                        is_outermost = False
                        break
            
            if is_outermost and paren_count == 0:
                predicate = predicate[1:-1].strip()
            else:
                break
        
        # 查找主要的逻辑操作符（从右到左，确保正确的优先级）
        # OR优先级低于AND，所以先处理OR
        for logical_op in [' OR ', ' AND ']:
            op_upper = logical_op.strip().upper()
            
            # 查找不在括号内的逻辑操作符
            parts = self._split_by_operator(predicate, logical_op.strip())
            
            if len(parts) > 1:
                # 递归解析各个部分
                sub_predicates = []
                for part in parts:
                    part = part.strip()
                    if part:
                        # 检查部分是否还包含逻辑操作符，如果有则递归调用
                        part_lower = part.lower()
                        if 'and' in part_lower or 'or' in part_lower:
                            sub_func = self._parse_complex_predicate(part)
                        else:
                            sub_func = self._parse_simple_condition(part)
                        sub_predicates.append(sub_func)
                
                # 构建复合谓词函数
                if op_upper == 'AND':
                    def and_predicate(record: Record) -> bool:
                        return all(sub_pred(record) for sub_pred in sub_predicates)
                    return and_predicate
                elif op_upper == 'OR':
                    def or_predicate(record: Record) -> bool:
                        return any(sub_pred(record) for sub_pred in sub_predicates)
                    return or_predicate
        
        # 如果没有找到逻辑操作符，按简单条件处理
        return self._parse_simple_condition(predicate)
    
    def _split_by_operator(self, predicate: str, operator: str) -> List[str]:
        """按操作符分割，但忽略括号内的操作符"""
        parts = []
        current_part = ""
        paren_count = 0
        i = 0
        op_len = len(operator)
        
        while i < len(predicate):
            if predicate[i] == '(':
                paren_count += 1
                current_part += predicate[i]
            elif predicate[i] == ')':
                paren_count -= 1
                current_part += predicate[i]
            elif paren_count == 0 and i + op_len <= len(predicate):
                # 检查是否匹配操作符
                potential_op = predicate[i:i + op_len]
                if potential_op.upper() == operator.upper():
                    # 找到操作符，分割
                    parts.append(current_part)
                    current_part = ""
                    i += op_len - 1  # 跳过操作符
                else:
                    current_part += predicate[i]
            else:
                current_part += predicate[i]
            i += 1
        
        if current_part:
            parts.append(current_part)
        
        return parts if len(parts) > 1 else [predicate]
    
    def _parse_simple_condition(self, condition: str) -> Callable[[Record], bool]:
        """解析简单条件（不包含AND/OR）"""
        condition = condition.strip()
        
        # 移除括号
        if condition.startswith('(') and condition.endswith(')'):
            condition = condition[1:-1].strip()
        
        # 处理LIKE操作符
        if ' LIKE ' in condition.upper():
            # 使用原始条件进行分割，保持字段名的原始大小写
            like_pos = condition.upper().find(' LIKE ')
            if like_pos != -1:
                column = condition[:like_pos].strip()
                pattern = condition[like_pos + 6:].strip().strip("'\"")
                # 转换SQL LIKE模式为正则表达式
                import re
                regex_pattern = pattern.replace('%', '.*').replace('_', '.')
                compiled_regex = re.compile(regex_pattern, re.IGNORECASE)
                
                return lambda record: (
                    record.get(column) is not None and
                    compiled_regex.search(str(record.get(column))) is not None
                )
        
        # 处理比较操作符
        operators_map = {
            '>=': operator.ge,
            '<=': operator.le,
            '!=': operator.ne,
            '=': operator.eq,
            '>': operator.gt,
            '<': operator.lt,
        }
        
        for op_str, op_func in operators_map.items():
            if op_str in condition:
                left_expr, right_expr = condition.split(op_str, 1)
                left_expr = left_expr.strip()
                right_expr = right_expr.strip()
                
                def simple_predicate(record: Record) -> bool:
                    try:
                        left_value = self._evaluate_expression(left_expr, record)
                        right_value = self._evaluate_expression(right_expr, record)
                        return op_func(left_value, right_value)
                    except:
                        return False
                
                return simple_predicate
        
        # 如果无法解析，返回默认
        return lambda record: True
    
    def _evaluate_expression(self, expr: str, record: Record) -> Any:
        """计算表达式值"""
        expr = expr.strip()
        
        # 如果是列名
        if expr in record:
            return record[expr]
        
        # 如果是字符串字面量
        if expr.startswith("'") and expr.endswith("'"):
            return expr[1:-1]
        
        if expr.startswith('"') and expr.endswith('"'):
            return expr[1:-1]
        
        # 如果是数字字面量
        try:
            if '.' in expr:
                return float(expr)
            else:
                return int(expr)
        except ValueError:
            pass
        
        # 布尔字面量
        if expr.lower() == 'true':
            return True
        elif expr.lower() == 'false':
            return False
        elif expr.lower() == 'null':
            return None
        
        # 如果都不是，返回字符串
        return expr
    
    def _parse_value(self, value_str: str) -> Any:
        """解析值"""
        return self._evaluate_expression(value_str, {})
    
    def open(self):
        """打开过滤操作符"""
        with self.lock:
            if self.is_open:
                return
            
            self.is_open = True
            
            # 打开子执行器
            self.child.open()
            
            # 创建过滤迭代器
            self.current_iterator = self._create_filter_iterator()
    
    def _create_filter_iterator(self) -> Iterator[Record]:
        """创建过滤迭代器"""
        while True:
            child_batch = self.child.next_batch()
            if not child_batch:
                break
            
            filtered_records = []
            
            for record in child_batch:
                self.check_timeout()
                
                # 更新处理统计
                self.update_stats(rows_processed=1)
                
                # 应用谓词过滤
                try:
                    if self.predicate_func and self.predicate_func(record):
                        filtered_records.append(record)
                        self.update_stats(rows_returned=1)
                except Exception:
                    # 谓词执行出错，跳过该记录
                    continue
            
            # 返回过滤后的记录
            for record in filtered_records:
                yield record
    
    def close(self):
        """关闭过滤操作符"""
        with self.lock:
            if not self.is_open:
                return
            
            # 关闭子执行器
            self.child.close()
            
            self.is_open = False
            self.current_iterator = None
    
    def get_estimated_selectivity(self) -> float:
        """获取估算选择性"""
        # 简化的选择性估算
        predicate_lower = self.predicate_str.lower()
        
        if 'is null' in predicate_lower:
            return 0.1  # 假设10%的记录为NULL
        elif 'is not null' in predicate_lower:
            return 0.9  # 假设90%的记录非NULL
        elif '=' in predicate_lower:
            return 0.1  # 等值比较选择性较低
        elif 'like' in predicate_lower:
            return 0.3  # LIKE操作选择性中等
        elif 'in' in predicate_lower:
            return 0.2  # IN操作选择性较低
        elif 'between' in predicate_lower:
            return 0.25  # BETWEEN操作选择性中等
        else:
            return 0.5  # 默认选择性

class CompositeFilterOperator(FilterOperator):
    """复合过滤操作符，支持AND/OR逻辑"""
    
    def __init__(self, executor_id: str, context: ExecutionContext,
                 child: IteratorExecutor, predicates: List[str], 
                 logical_op: str = "AND"):
        self.predicates = predicates
        self.logical_op = logical_op.upper()
        
        # 构建复合谓词字符串
        if self.logical_op == "AND":
            combined_predicate = " AND ".join(f"({p})" for p in predicates)
        elif self.logical_op == "OR":
            combined_predicate = " OR ".join(f"({p})" for p in predicates)
        else:
            raise ValueError(f"Unsupported logical operator: {logical_op}")
        
        super().__init__(executor_id, context, child, combined_predicate)
        
        # 编译各个子谓词
        self.sub_predicates: List[Callable[[Record], bool]] = []
        for predicate in predicates:
            sub_func = self._create_predicate_function(predicate)
            self.sub_predicates.append(sub_func)
    
    def _create_predicate_function(self, predicate: str) -> Callable[[Record], bool]:
        """重写谓词函数创建，处理复合逻辑"""
        if self.logical_op == "AND":
            def and_predicate(record: Record) -> bool:
                for sub_pred in self.sub_predicates:
                    if not sub_pred(record):
                        return False
                return True
            return and_predicate
        
        elif self.logical_op == "OR":
            def or_predicate(record: Record) -> bool:
                for sub_pred in self.sub_predicates:
                    if sub_pred(record):
                        return True
                return False
            return or_predicate
        
        else:
            return super()._create_predicate_function(predicate)

class DynamicFilterOperator(FilterOperator):
    """动态过滤操作符，支持运行时修改谓词"""
    
    def __init__(self, executor_id: str, context: ExecutionContext,
                 child: IteratorExecutor):
        super().__init__(executor_id, context, child, "true")  # 默认不过滤
        self.active_predicates: List[Callable[[Record], bool]] = []
        self.predicate_stats: Dict[str, Dict[str, int]] = {}
    
    def add_predicate(self, predicate: str, predicate_id: str = None):
        """添加谓词"""
        if predicate_id is None:
            predicate_id = f"pred_{len(self.active_predicates)}"
        
        predicate_func = self._create_predicate_function(predicate)
        self.active_predicates.append(predicate_func)
        
        # 初始化统计信息
        self.predicate_stats[predicate_id] = {
            'applied': 0,
            'passed': 0,
            'failed': 0
        }
    
    def remove_predicate(self, predicate_index: int):
        """移除谓词"""
        if 0 <= predicate_index < len(self.active_predicates):
            self.active_predicates.pop(predicate_index)
    
    def clear_predicates(self):
        """清空所有谓词"""
        self.active_predicates.clear()
        self.predicate_stats.clear()
    
    def _create_filter_iterator(self) -> Iterator[Record]:
        """重写过滤迭代器，应用动态谓词"""
        while True:
            child_batch = self.child.next_batch()
            if not child_batch:
                break
            
            for record in child_batch:
                self.check_timeout()
                self.update_stats(rows_processed=1)
                
                # 应用所有活动谓词
                passed = True
                for i, predicate_func in enumerate(self.active_predicates):
                    try:
                        pred_id = f"pred_{i}"
                        if pred_id in self.predicate_stats:
                            self.predicate_stats[pred_id]['applied'] += 1
                        
                        if not predicate_func(record):
                            passed = False
                            if pred_id in self.predicate_stats:
                                self.predicate_stats[pred_id]['failed'] += 1
                            break
                        else:
                            if pred_id in self.predicate_stats:
                                self.predicate_stats[pred_id]['passed'] += 1
                    except Exception:
                        passed = False
                        break
                
                if passed:
                    self.update_stats(rows_returned=1)
                    yield record
    
    def get_predicate_stats(self) -> Dict[str, Dict[str, int]]:
        """获取谓词统计信息"""
        return self.predicate_stats.copy()

